
package Seguridad;

import java.awt.Frame;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Arrays;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Funciones {

    KeyPairGenerator generadorLlaves;
    KeyPair parLlave;
    Cipher cifrarMensaje;
    byte[] textoFinal;

    public Funciones() {
        generadorLlaves = null;
        parLlave = null;
        cifrarMensaje = null;
        textoFinal = null;
    }
    
        /**
     * devuelve el hash de un mensaje, se realiza por MD5
     *
     * @param password texto al cual se le obtiene el hash
     * @pa
     * @see
     */
    
    //-----------------------------MD5---------------------------------------
    
  public String md5(String password) throws NoSuchAlgorithmException{  
    
    MessageDigest mdAlgorithm = MessageDigest.getInstance("MD5");
        mdAlgorithm.update(password.getBytes());

        byte[] digest = mdAlgorithm.digest();
        StringBuffer hexString = new StringBuffer();

        for (int i = 0; i < digest.length; i++)
        
            {
                password = Integer.toHexString(0xFF & digest[i]);

                if (password.length() < 2) 
                    {
                        password = "0" + password;
                    }

                hexString.append(password);
            }

        password= hexString.toString();
        return password;
}
  
  //-----------------------------FIN MD5-------------------------------
  
  

    public String formatoClave(Key key) {
        StringBuffer sb = new StringBuffer();
        String algo = key.getAlgorithm();
        String fmt = key.getFormat();
        byte[] encoded = key.getEncoded();
        sb.append("Key[algorithm=" + algo + ", format=" + fmt + ", bytes=" + encoded.length + "]\n");
        //if (fmt.equalsIgnoreCase("RAW")){
        //sb.append("Key Material (in hex):: ");
        //sb.append(Util.byteArray2Hex(key.getEncoded()));
        //}

        return sb.toString();
    }

    public KeyPair generarLlave() {
        try {
            generadorLlaves = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
        }

        generadorLlaves.initialize(1024);
        parLlave = generadorLlaves.generateKeyPair();

        return parLlave;
    }

    public void inicializarCifrado() throws NoSuchAlgorithmException {
        try {
            cifrarMensaje = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // Instancia del que encripta datos
        } catch (NoSuchPaddingException ex) {
            Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Este es la info respecto a la funcion cifrarDescifrar(). es un Metodo
     * para cifrar o descifrar algun mensaje
     *
     * @param modo es el modo que recibe, toma valores enteros y se refiere si
     * quiere cifrar o descifrar
     * @param tipoLlave necesario para aplicar el cifrado
     * @pa
     * @see
     */
    public byte[] cifrarDescifrar(int modo, Key tipoLlave, byte[] texto) throws NoSuchAlgorithmException, IllegalBlockSizeException {

        inicializarCifrado();

        try {
            cifrarMensaje.init(modo, tipoLlave);
        } catch (InvalidKeyException ex) {
            Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
        }

        try {
            textoFinal = cifrarMensaje.doFinal(texto); //inicio de cifrado
        } catch (BadPaddingException ex) {
            Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
        }

        return textoFinal;
    }

    public String [] enviarKeyString(KeyPair llavesGeneradas) {
        String[] v = new String[2];
        v[0] = llavesGeneradas.getPrivate().toString();
        v[1] = llavesGeneradas.getPublic().toString();

        return v;
    }
    
/**
     * CIFRAR MENSAJE 3DES. es un Metodo
     * para cifrar  algun mensaje en 3DES
     *
     * @param recibe parametro el mensaje que se quiere cifrar
     * @pa
     * @see
     */
    
    public byte[] encrypt(String message) throws Exception 
            {
                
                String claveCifrado="redes";
                
                MessageDigest md = MessageDigest.getInstance("md5");
                byte[] digestOfPassword = md.digest(claveCifrado.getBytes("utf-8"));
                byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
                
                for (int j = 0, k = 16; j < 8;) 
                    {
                        keyBytes[k++] = keyBytes[j++];
                    }

                SecretKey key = new SecretKeySpec(keyBytes, "DESede");
                IvParameterSpec iv = new IvParameterSpec(new byte[8]);
            
                Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, key, iv);

                byte[] plainTextBytes = message.getBytes("utf-8");
                byte[] cipherText = cipher.doFinal(plainTextBytes);
           
                return cipherText;
        }
    
   /**
     * desCIFRAR MENSAJE 3DES. es un Metodo
     * para descifrar  algun mensaje en 3DES
     *
     * @param recibe parametro el mensaje cifrado en tipo byte[] que se quiere descifrar
     * @pa
     * @see
     */
     
    
    public String decrypt(byte[] message) throws Exception {
        
        String claveCifrado="redes";
                
            MessageDigest md = MessageDigest.getInstance("md5");
            
            byte[] digestOfPassword = md.digest(claveCifrado.getBytes("utf-8"));
            byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
            
            for (int j = 0, k = 16; j < 8;) {
                    keyBytes[k++] = keyBytes[j++];
            }

            SecretKey key = new SecretKeySpec(keyBytes, "DESede");
            IvParameterSpec iv = new IvParameterSpec(new byte[8]);
            Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
            decipher.init(Cipher.DECRYPT_MODE, key, iv);

            byte[] plainText = decipher.doFinal(message);

            return new String(plainText, "UTF-8");
        }
    
 
        
    
}
